package com.tsky.casing.orm.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.tsky.casing.orm.EntityManager;

/**
 * ORM基本操作的实现类
 * @author: cainiao
 * @version 1.0 
 * @time: 2010-4-21 下午02:47:39
 */
public class EntityManagerImpl extends HibernateDaoSupport implements EntityManager {

	@Autowired
	public void setSessionFactoryOverride(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}
	
	public boolean delEntity(Class<?> classType, Object id) {
		// TODO Auto-generated method stub
		try {
			Object entity = this.getHibernateTemplate().get(classType, (Serializable)id);
			this.getHibernateTemplate().delete(entity);
			return true;
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	private List getEntityList(Class<?> classType, Object[] ids){
		List entityList = new ArrayList();
		for (Object id : ids) {
			Object entity = this.getHibernateTemplate().get(classType, (Serializable)id);
			if (entity != null) {
				entityList.add(entity);
			}
		}
		return entityList;
	}
	
	public boolean delEntity(Class<?> classType, Object[] ids) {
		// TODO Auto-generated method stub
		try {
			this.getHibernateTemplate().deleteAll(getEntityList(classType, ids));
			return true;
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public boolean saveEntity(Object entity) {
		// TODO Auto-generated method stub
		try {
			this.getHibernateTemplate().save(entity);
			return true;
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}

	public boolean updateEntity(Object entity) {
		// TODO Auto-generated method stub
		try {
			this.getHibernateTemplate().update(entity);
			return true;
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}
	
//	public Object getEntity(Class<T> classType, Object id) {
//		// TODO Auto-generated method stub
//		return this.getHibernateTemplate().get(classType, (Serializable)id);
//	}
	
	public <T> T getEntity(Class<T> classType, Object id) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().get(classType, (Serializable)id);
	}

	private Criteria criteria(Class<?> classType) {
		return this.getSession().createCriteria(classType);
	}
	
//	public List<?> getAllEntity(Class<?> classType) {
//		// TODO Auto-generated method stub
//		return this.getHibernateTemplate().loadAll(classType);
//	}
	
	public <T> List<T> getAllEntity(Class<T> classType) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().loadAll(classType);
	}

	public <T> List<T> getAllEntity(Class<T> classType, int size) {
		// TODO Auto-generated method stub
		return this.criteria(classType).setMaxResults(size).list();
	}

	public <T> List<T> getAllEntity(Class<T> classType, Object status) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.eq("status", status)).list();
	}

	public <T> List<T> getAllEntity(Class<T> classType, Object status, int size) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.eq("status", status)).setMaxResults(size).list();
	}

	public <T> List<T> getAllEntity(Class<T> classType, Object[] ids) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.in("id", ids)).list();
	}

	public <T> List<T> getAllEntityByField(Class<T> classType, String field, Object value) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.eq(field, value)).list();
	}

	public <T> List<T> getAllEntity(Class<T> classType, String field, String order) {
		// TODO Auto-generated method stub
		List<T> list = null;
		if ("ASC".equalsIgnoreCase(order)) {
			list = this.criteria(classType).addOrder(Order.asc(field)).list();
		}
		if("DESC".equalsIgnoreCase(order)) {
			list = this.criteria(classType).addOrder(Order.desc(field)).list();
		}
		return list;
	}

	public Object avg(String tableName, String field) {
		// TODO Auto-generated method stub
		// this.getHibernateTemplate().
		return this.getHibernateTemplate().find("select avg(a."+ field +") from "+ tableName +" a").iterator().next();
	}

	public <T> List<T> getAllEntityByField(Class<T> classType, String field,
			Object[] values) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.in(field, values)).list();
	}
	
	public <T> List<T> getAllEntityByField(Class<T> classType, String field,
			Collection values) {
		// TODO Auto-generated method stub
		return this.criteria(classType).add(Restrictions.in(field, values)).list();
	}

	public <T> List<T> getAllEntityByField(Class<T> classType, String field,
			Object value, String orderfield, String order) {
		// TODO Auto-generated method stub
		List<T> list = null;
		if ("ASC".equalsIgnoreCase(order)) {
			list = this.criteria(classType).add(Restrictions.eq(field, value))
					.addOrder(Order.asc(orderfield)).list();
		}
		if("DESC".equalsIgnoreCase(order)) {
			list = this.criteria(classType).add(Restrictions.eq(field, value)).
					addOrder(Order.desc(orderfield)).list();
		}
		return list;
	}
	
	public <T> List<T> getAllEntityByField(Class<T> classType, Map<String,Object[]> fields) {
		// TODO Auto-generated method stub
		Criteria myCriteria = this.criteria(classType); 
		for(Map.Entry<String, Object[]> entry:fields.entrySet()){
			myCriteria.add(Restrictions.in(entry.getKey(), entry.getValue()));
		}
		return myCriteria.list();
	}
}
